/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.je.bpm.engine.impl.el;

import com.je.bpm.engine.delegate.VariableScope;
import com.je.bpm.engine.impl.persistence.entity.VariableInstance;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;

/**
 * Variable-scope only used to resolve variables when NO execution is active but expression-resolving is needed. This occurs eg. when start-form properties have default's defined. Even though
 * variables are not available yet, expressions should be resolved anyway.
 */
public class NoExecutionVariableScope implements VariableScope {

    private static final NoExecutionVariableScope INSTANCE = new NoExecutionVariableScope();

    /**
     * Since a {@link NoExecutionVariableScope} has no state, it's safe to use the same instance to prevent too many useless instances created.
     */
    public static NoExecutionVariableScope getSharedInstance() {
        return INSTANCE;
    }

    @Override
    public Map<String, Object> getVariables() {
        return emptyMap();
    }

    @Override
    public Map<String, Object> getVariablesLocal() {
        return emptyMap();
    }

    @Override
    public Map<String, Object> getVariables(Collection<String> variableNames) {
        return emptyMap();
    }

    @Override
    public Map<String, Object> getVariables(Collection<String> variableNames, boolean fetchAllVariables) {
        return emptyMap();
    }

    @Override
    public Map<String, Object> getVariablesLocal(Collection<String> variableNames) {
        return emptyMap();
    }

    @Override
    public Map<String, Object> getVariablesLocal(Collection<String> variableNames, boolean fetchAllVariables) {
        return emptyMap();
    }

    @Override
    public Object getVariable(String variableName) {
        return null;
    }

    @Override
    public Object getVariable(String variableName, boolean fetchAllVariables) {
        return null;
    }

    @Override
    public Object getVariableLocal(String variableName) {
        return null;
    }

    @Override
    public Object getVariableLocal(String variableName, boolean fetchAllVariables) {
        return null;
    }

    @Override
    public <T> T getVariable(String variableName, Class<T> variableClass) {
        return null;
    }

    @Override
    public <T> T getVariableLocal(String variableName, Class<T> variableClass) {
        return null;
    }

    @Override
    public Map<String, VariableInstance> getVariableInstances() {
        return null;
    }

    @Override
    public Map<String, VariableInstance> getVariableInstances(Collection<String> variableNames) {
        return null;
    }

    @Override
    public Map<String, VariableInstance> getVariableInstances(Collection<String> variableNames, boolean fetchAllVariables) {
        return null;
    }

    @Override
    public Map<String, VariableInstance> getVariableInstancesLocal() {
        return null;
    }

    @Override
    public Collection<VariableInstance> getVariableInstancesLocalList() {
        return null;
    }

    @Override
    public Map<String, VariableInstance> getVariableInstancesLocal(Collection<String> variableNames) {
        return null;
    }

    @Override
    public Map<String, VariableInstance> getVariableInstancesLocal(Collection<String> variableNames, boolean fetchAllVariables) {
        return null;
    }

    @Override
    public VariableInstance getVariableInstance(String variableName) {
        return null;
    }

    @Override
    public VariableInstance getVariableInstance(String variableName, boolean fetchAllVariables) {
        return null;
    }

    @Override
    public VariableInstance getVariableInstanceLocal(String variableName) {
        return null;
    }

    @Override
    public VariableInstance getVariableInstanceLocal(String variableName, boolean fetchAllVariables) {
        return null;
    }

    @Override
    public Set<String> getVariableNames() {
        return emptySet();
    }

    @Override
    public Set<String> getVariableNamesLocal() {
        return null;
    }

    @Override
    public void setVariable(String variableName, Object value) {
        throw new UnsupportedOperationException("No execution active, no variables can be set");
    }

    @Override
    public void setVariable(String variableName, Object value, boolean fetchAllVariables) {
        throw new UnsupportedOperationException("No execution active, no variables can be set");
    }

    @Override
    public Object setVariableLocal(String variableName, Object value) {
        throw new UnsupportedOperationException("No execution active, no variables can be set");
    }

    @Override
    public Object setVariableLocal(String variableName, Object value, boolean fetchAllVariables) {
        throw new UnsupportedOperationException("No execution active, no variables can be set");
    }

    @Override
    public void setVariables(Map<String, ? extends Object> variables) {
        throw new UnsupportedOperationException("No execution active, no variables can be set");
    }

    @Override
    public void setVariablesLocal(Map<String, ? extends Object> variables) {
        throw new UnsupportedOperationException("No execution active, no variables can be set");
    }

    @Override
    public boolean hasVariables() {
        return false;
    }

    @Override
    public boolean hasVariablesLocal() {
        return false;
    }

    @Override
    public boolean hasVariable(String variableName) {
        return false;
    }

    @Override
    public boolean hasVariableLocal(String variableName) {
        return false;
    }

    public void createVariableLocal(String variableName, Object value) {
        throw new UnsupportedOperationException("No execution active, no variables can be created");
    }

    public void createVariablesLocal(Map<String, ? extends Object> variables) {
        throw new UnsupportedOperationException("No execution active, no variables can be created");
    }

    @Override
    public void removeVariable(String variableName) {
        throw new UnsupportedOperationException("No execution active, no variables can be removed");
    }

    @Override
    public void removeVariableLocal(String variableName) {
        throw new UnsupportedOperationException("No execution active, no variables can be removed");
    }

    @Override
    public void removeVariables() {
        throw new UnsupportedOperationException("No execution active, no variables can be removed");
    }

    @Override
    public void removeVariablesLocal() {
        throw new UnsupportedOperationException("No execution active, no variables can be removed");
    }

    @Override
    public void removeVariables(Collection<String> variableNames) {
        throw new UnsupportedOperationException("No execution active, no variables can be removed");
    }

    @Override
    public void removeVariablesLocal(Collection<String> variableNames) {
        throw new UnsupportedOperationException("No execution active, no variables can be removed");
    }

    @Override
    public void setTransientVariablesLocal(Map<String, Object> transientVariables) {
        throw new UnsupportedOperationException("No execution active, no variables can be set");
    }

    @Override
    public void setTransientVariableLocal(String variableName, Object variableValue) {
        throw new UnsupportedOperationException("No execution active, no variables can be set");
    }

    @Override
    public void setTransientVariables(Map<String, Object> transientVariables) {
        throw new UnsupportedOperationException("No execution active, no variables can be set");
    }

    @Override
    public void setTransientVariable(String variableName, Object variableValue) {
        throw new UnsupportedOperationException("No execution active, no variables can be set");
    }

    @Override
    public Object getTransientVariableLocal(String variableName) {
        return null;
    }

    @Override
    public Map<String, Object> getTransientVariablesLocal() {
        return null;
    }

    @Override
    public Object getTransientVariable(String variableName) {
        return null;
    }

    @Override
    public Map<String, Object> getTransientVariables() {
        return null;
    }

    @Override
    public void removeTransientVariableLocal(String variableName) {
        throw new UnsupportedOperationException("No execution active, no variables can be removed");
    }
    
    @Override
    public void removeTransientVariablesLocal() {
        throw new UnsupportedOperationException("No execution active, no variables can be removed");
    }

    @Override
    public void removeTransientVariable(String variableName) {
        throw new UnsupportedOperationException("No execution active, no variables can be removed");
    }

    @Override
    public void removeTransientVariables() {
        throw new UnsupportedOperationException("No execution active, no variables can be removed");
    }
}
